import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
import matplotlib.gridspec as gridspec

plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False

initial_alpha = 0.5   
initial_delta = 2.0   

t = np.arange(0, 10, 0.1)
error = np.linspace(0, 10, len(t))

def fal(e, alpha, delta):
    result = np.zeros_like(e)
    mask = np.abs(e) > delta
    result[mask] = np.abs(e[mask]) ** alpha * np.sign(e[mask])
    result[~mask] = e[~mask] / (delta ** (1 - alpha))
    return result

fig = plt.figure(figsize=(10, 6))
gs = gridspec.GridSpec(2, 1, height_ratios=[5, 1]) 
ax = fig.add_subplot(gs[0])
plt.subplots_adjust(left=0.1, bottom=0.3)

processed_error = fal(error, initial_alpha, initial_delta)
line1, = ax.plot(t, error, label='原始误差', color='blue', linestyle='--')
line2, = ax.plot(t, processed_error, label='fal处理后误差', color='red')

ax.set_xlabel('t')
ax.set_ylabel('e')
ax.set_title('fal函数')
ax.legend()
ax.grid(True)
ax.set_ylim(-1, 11) 

ax_alpha = plt.axes([0.1, 0.2, 0.8, 0.03]) 
ax_delta = plt.axes([0.1, 0.15, 0.8, 0.03])

slider_alpha = Slider(ax_alpha, '非线性指数 α', 0.1, 0.9, valinit=initial_alpha, valstep=0.05)
slider_delta = Slider(ax_delta, '线性区间阈值 δ', 0.1, 5.0, valinit=initial_delta, valstep=0.1)

def update(val):
    alpha = slider_alpha.val
    delta = slider_delta.val
    new_processed = fal(error, alpha, delta)
    line2.set_ydata(new_processed)
    fig.canvas.draw_idle()

slider_alpha.on_changed(update)
slider_delta.on_changed(update)

reset_ax = plt.axes([0.4, 0.05, 0.2, 0.04])
button = Button(reset_ax, '重置参数')

def reset(event):
    slider_alpha.reset()
    slider_delta.reset()

button.on_clicked(reset)

plt.show()
